home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dr. Windows 3
/
dr win3.zip
/
dr win3
/
WINPROGS
/
DRDOBBS.ZIP
/
HELPDUMP.C
< prev
next >
Wrap
Text File
|
1993-08-02
|
41KB
|
1,233 lines
/***************************************************
HLPDUMP1.C
Peter Davis - 05/93
Taken from the original HELPDUMP.C written by
Ron Burk.
Dumps known files from WinHelp internal file
system in a formatted output. If WHIFS file is
unknown, hex/ascii dump of file is taken.
HELPDUMP.C will replace HLPDUMP1.C with extended
functionality for handling more WHIFS files.
****************************************************/
/*************************************************
If it's not Turbo C, assume MSC 6.0 As for the
rest of you, you'll have to customize. Sorry.
**************************************************/
#pragma pack(1) /* Make sure we get byte alignment */
#ifndef __TURBOC__
#include <graph.h>
#define clrscr() _clearscreen(_GCLEARSCREEN);
#endif
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <ctype.h>
#include <limits.h>
#include "whstruct.h"
#include "helpdump.h"
HELPHEADER HelpHeader; /* Header for Help file. */
WHIFSBTREEHEADER WHIFSHeader; /* WHIFS Header record */
int WHIFSLeafOne = -1; /* First WHIFS Leaf Node */
long FirstPageLoc; /* Used by macros for b-trees */
char WHIFSFileToRead[19]; /* Internal file to dump */
int ReadWHIFSFile; /* Flag to dump an internal file */
SYSTEMHEADER SysHeader; /* Global System Header Record */
char *PhrasesPtr;
int TopicUse;
/***************************************************
Finds the first leaf in the WHIFS B-Tree
****************************************************/
void WHIFSGetFirstLeaf(FILE *HelpFile) {
int CurrLevel = 1; /* Current Level in B-Tree */
BTREEINDEXHEADER CurrNode; /* Current Node in B-Tree */
int NextPage = 0; /* Next Page to go to */
/* Go to the beginning of WHIFS B-Tree */
fseek(HelpFile, HelpHeader.WHIFS, SEEK_SET);
fread(&WHIFSHeader, sizeof(WHIFSHeader), 1, HelpFile);
FirstPageLoc = HelpHeader.WHIFS + sizeof(WHIFSHeader);
/* Find First Leaf */
while (CurrLevel < WHIFSHeader.NLevels) {
fread(&CurrNode, sizeof(CurrNode), 1, HelpFile);
/* Next Page is conveniently the first byte of the page */
fread(&NextPage, sizeof(int), 1, HelpFile);
GotoWHIFSPage(NextPage);
CurrLevel++;
}
/* First Leaf page is here */
WHIFSLeafOne = NextPage;
}
/***************************************************
Gets a particular file by file number.
Needs the root node of the tree.
Returns the offset of the file and the filename.
****************************************************/
void GetFile(FILE *HelpFile, int FileNumber, long *FileOffset, char *FileName) {
BTREENODEHEADER CurrentNode;
int CurrPage; /* Keep track of page # */
int Index, counter = 0;
char c, TempFile[19];
/* Skip pages we don't need */
CurrentNode.NextPage = WHIFSLeafOne;
do {
CurrPage = CurrentNode.NextPage;
GotoWHIFSPage(CurrPage);
fread(&CurrentNode, sizeof(CurrentNode), 1, HelpFile);
counter += CurrentNode.NEntries;
} while (counter < FileNumber);
for (counter -= CurrentNode.NEntries; counter <= FileNumber; counter++) {
Index = 0;
while(c = fgetc(HelpFile))
TempFile[Index++] = c;
TempFile[Index] = 0; /* End of line */
fread(FileOffset, sizeof(long), 1, HelpFile);
}
strcpy(FileName, TempFile);
}
/***************************************************
Loads the SysHeader into memory. Need this later
on to determine if compression is used on help file.
****************************************************/
void SysLoad(FILE *HelpFile, long FileStart) {
FILEHEADER FileHdr;
fseek(HelpFile, FileStart, SEEK_SET);
fread(&FileHdr, sizeof(FileHdr), 1, HelpFile);
fread(&SysHeader, sizeof(SysHeader), 1, HelpFile);
}
/*************************************************
Returns a 1 if the bit is set, else 0 returned
**************************************************/
int BitSet(BYTE BitMap, int Bit) {
if (BitMap & (1<<Bit)) return 1;
else return 0;
}
/*************************************************
Decides how many bytes to read, depending on the
number of bits set in the Bitmap
**************************************************/
int BytesToRead(BYTE BitMap) {
int TempSum, counter;
TempSum = 8;
for (counter = 0; counter < 8; counter ++)
TempSum += BitSet(BitMap, counter);
return TempSum;
}
/*************************************************
Decompresses the data using Microsoft's LZ77
derivative.
**************************************************/
WORD Decompress(FILE *HelpFile, WORD CompSize, char *Buffer) {
WORD InBytes = 0; /* How many bytes read in */
WORD OutBytes = 0; /* How many bytes written out */
BYTE BitMap, Set[16]; /* Bitmap and bytes associated with it */
int NumToRead; /* Number of bytes to read for next group */
int counter, Index; /* Going through next 8-16 codes or chars */
int Length, Distance; /* Code length and distance back in 'window' */
char *CurrPos; /* Where we are at any given moment */
char *CodePtr; /* Pointer to back-up in LZ77 'window' */
CurrPos = Buffer;
/* Go through until we're done */
while (InBytes < CompSize) {
/* Get BitMap and data following it */
BitMap = fgetc(HelpFile);
NumToRead = BytesToRead(BitMap);
/* If we're trying to read more than we've got left, only read what we have left. */
NumToRead = (CompSize - InBytes) < NumToRead ? CompSize-InBytes : NumToRead;
fread(Set, 1, NumToRead, HelpFile);
InBytes += NumToRead + 1;
/* Go through and decode data */
for (counter = 0, Index = 0; counter < 8; counter++) {
/* It's a code, so decode it and copy the data */
if (BitSet(BitMap, counter)) {
Length = ((Set[Index+1] & 0xF0) >> 4) + 3;
Distance = (256 * (Set[Index+1] & 0x0F)) + Set[Index] + 1;
CodePtr = CurrPos - Distance;
/* Copy data from 'window' */
while (Length) {
*CurrPos++ = *CodePtr++;
OutBytes++;
Length--;
}
Index += 2;
} /* if */
else {
*CurrPos++ = Set[Index++];
OutBytes++;
}
} /* for */
} /* while */
return OutBytes;
}
/***************************************************
List the WHIFS directory to the screen.
****************************************************/
void ListFiles(FILE *HelpFile) {
DWORD FileCounter;
char FileName[20];
long FileOffset;
/* Load WHIFS Header and Get first leaf */
WHIFSGetFirstLeaf(HelpFile);
for (FileCounter = 0;
FileCounter < WHIFSHeader.TotalWHIFSEntries;
FileCounter++) {
GetFile(HelpFile, FileCounter, &FileOffset, FileName);
printf("File:%-10s FileOffset:0x%08lX ",FileName, FileOffset);
/* Make it double column */
if ((FileCounter % 2) != 0) printf("\n");
else printf("|");
}
}
/***************************************************
Performs a Hex/ASCII dump of a WHIFS file.
****************************************************/
void HexDump(FILE *HelpFile, long FileStart) {
FILEHEADER FileHdr;
char Buffer[16];
long counter;
int BytesToPrint, Index;
fseek(HelpFile, FileStart, SEEK_SET);